<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>js运行机制/event Loop（事件循环怎么理解的？</title>
</head>

<body>

  <script>
    //同步与异步相关面试题？
    /*  console.log(1);
     setTimeout(() => {
       console.log(2);
     }, 0)
     console.log(3); */


    //1.1 输出结果,并写出为什么 ？
    /*  for (var i = 0; i <= 5; i++) {
       console.log('正常同步', i)  //这还是同步呢
       setTimeout(() => {
         console.log(i); //输出6个6。因为变成异步了，同步已经走完了，变成了6
       }, 1000)
     } */


    //1.2 以上代码如果想输出6,0,1,2,3,4,5,怎么实现?
    //自执行函数-自动执行不需要调用 ((形参)=>{})(实参); 或者 (()=>{}())  !!!注意，自执行函数前后别忘记加分号;否则为报错
    /*  let a = '2b青年';
     ((c) => {
       console.log('自执行函数', c);
     })(a) */

    //自执行函数包完，变成同步了
    /*    for (var i = 0; i <= 5; i++) {
              //a是形参
                ((a)=>{
                  setTimeout(() => {
                      console.log(a);
                  }, a* 1000)
              }//i是实参,接受外部参数
             )(i);
          }
          console.log(i);   */

    // 输出结果6,0,1,2,3,4,5
    // 因为for循环是同步,定时器是异步,所以输出6个0。通过自执行函数可实现((参数)=>{})(接受外部参数)。


    //1.3 通过let也可实现,let是块级作用域
    /*   for (let i = 0; i <= 5; i++) {
            setTimeout(() => {
                    console.log(i);
                }, i * 1000)
          }
          // console.log(i); //但是这里会报错 */

    //3.1  event loop 事件循环题

    /*  setTimeout(() => {
       console.log(1);  //宏任务
     }, 0)
     new Promise((resolve, reject) => {
       console.log(2);  //同步
       resolve()
     }).then(() => {
       console.log(4); //微任务
     })
     console.log('3');   //结果 2，3，4，1
 
     //执行优先级 1.同步(promise里除了resolve的.then是异步请求。其它写的都是同步)>异步(微任务[promise的.then,async,await,axios]>宏任务[定时器,事件函数,ajax]) */


    //3.2 输出结果
    /*    let fn = async () => {
         console.log(3); //没有await前都是同步
         //  await console.log(5);  //输出的是3，5，1，4   await后面要的是异步请求结果,如果不是，会直接返回相当于同步。
         await setTimeout(() => { //await后面是阻塞的 ,定时器是宏任务,也会有顺序
           console.log(2);
         }, 1000);
         // console.log(4);
         await setTimeout(() => {
           console.log(4);
         }, 0);
       }
       fn()
       console.log(1);  // 最后结果3,1,4,2  
    */
    //3.3 输出结果
    /*   new Promise((resolve, reject) => {
        resolve(1);
        console.log(3);  //同步
      }).then((arg) => {
        console.log(arg);
      })
      setTimeout(() => {
        console.log(4);
      }, 0)
      console.log(5); //输出结果 3,5,1,4 */


    //3.4 变化下
    /*   new Promise((resolve, reject) => {
        resolve(
          (() => {  //这里是自执行函数
            console.log(1);
            return 2  //返回结果-resolve拿到了1个结果2
          })()
        );
        console.log(3);  //同步
      }).then((arg) => {
        console.log(arg);
      })
      setTimeout(() => {
        console.log(4);
      }, 0)
      console.log(5);   //输出结果 1,3,5,2,4   */


    // 3.4 事件循环进阶题
    async function async1() {
      console.log('1') //-2
      await async2()  //注意此处加await，会阻塞后面代码执行。不加的话不影响
      console.log('2') //-6，微任务.then
    }
    async function async2() {
      console.log('3')  //-3
    }

    console.log('4') //同步-1

    setTimeout(function () {
      console.log('5') //-8  宏任务
    }, 0)

    async1() //同步-2

    new Promise(function (resolve) {
      console.log('6')  //注意此处，在这里也是同步 -4
      resolve()  //这是异步
    }).then(function () {
      console.log('7') //-7  微任务
    })
    console.log('8')   //同步 5  

     //最后返回结果 4,1,3,6,8,2,7,5  


    /*  //4.面试题-你对事件循环evnet loop怎么理解？
        Event Loop（事件循环）解释：  js是一个单线程,异步io语言。单线程意味着堵塞,为了解决堵塞问题,js把任务分成了同步和异步任务，它们会分别进入不同的执行“场所”，同步进入主线程，异步进入任务队列。主线程内的任务执行完毕为空，就去任务队列读取对应的函数，进入主线程执行。只要主线程空了，就会读取任务列队，上述过程会不断重复，也就是常说的Event Loop（事件循环）。

        JS异步任务队列还有一个机制，就是遇到宏任务，先执行宏任务，将宏任务放入宏任务队列，然后再执行微任务，将微任务放入微任务队列，但是，这两个队列不是一个队列。当你往外拿的时候先从微任务队列里拿这个回调函数，然后再从宏任务的队列里拿宏任务的回调函数，也就是宏任务是先进后出,微任务后进先出。

        咱们看代码执行顺序的时候是 ：主线程(同步的) > 微任务(promise(同步的).then(异步的),async,await,$nexttick,axios等> 宏任务(js内置的方法：定时器,ajax,事件函数等)

       参考链接-https://blog.csdn.net/weixin_43638968/article/details/108941287
      */

  </script>
</body>

</html>